// 1. 创建对象的方式
    // (1). 字面量；(2) new Object() + 添加属性和方法

// 2. 属性类型 Object.definePerproty()
    //  数据属性
    // [[Configureable]]  [[Enumerable]] [[Writeable]] [[Value]]

        // a. Object.definedProperty 修改
        // b. configureable 设置为false后具有不可逆性
        let person = {};
        Object.defineProperty(person, 'name', {
            configureable: false,
            value: 'Katrina',
        });

        Object.defineProperty(person, 'name', {
            configureable: true,
            value: 'Katrina',
        });


    // 访问器属性
        // [[Configureable]]  [[Enumerable]] [[Get]](读取时调用) [[Set]] (写入时被调用)
        
        let book = {
            year_: 2017,
            edition: 1,
        };

        Object.defineProperty(book, 'year', {
            get() {
                return this.year_;
            },

            set(newValue) {
                if (newValue > 2017) {
                    this.year_ = newValue;
                    this.edition += (newValue - 2017);
                };
            },
        });
        console.log(book.year);   // 2017
        book.year = 2018;
        console.log(book.edition);   // 2

// 3. 定义多个属性 Object.defineProperties()

// 4. 读取属性的特性 Object.getOwnPropertyDescriptor()    Object.getOwnPropertyDescriptors()

// 5. 合并对象 Object.assign()
        // 1) 目标对象被修改
        // 2) 源对象浅拷贝

let obj1 = {
    name: 'Katrina',
};

let obj2 = {
    age: 18,
    ho: [1,2,3],
};

Object.assign(obj1, obj2);
obj2.ho[2] = 20;
console.log(obj1, obj2);   // { name: 'Katrina', age: 18, ho: [ 1, 2, 20 ] } { age: 18, ho: [ 1, 2, 20 ] }


// 6. 对象标识及相等判定
    // 改进特殊情况1： 两个NaN相等
    // 改进特殊情况2： -0 和 +0的问题

// 7. 增强对象语法
    // (1). 属性名和属性值一样
    // (2). 可计算属性
    const nameKey = 'name';
    const ageKey = 'age';

    const a = {};
    a[nameKey] = 'Karina';
    a[ageKey] = 18;

    console.log(a);   // { name: 'Karina', age: 18 }
    // (3). 简写方法名
        // say: function(){}   => say(){}; 


// 8. 对象解构